package it.univaq.di.helpdesk.business.common.impl.ibatis;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.ibatis.sqlmap.client.SqlMapClient;

import it.univaq.di.helpdesk.business.common.DeviceService;
import it.univaq.di.helpdesk.business.errors.BusinessException;
import it.univaq.di.helpdesk.business.model.Computer;
import it.univaq.di.helpdesk.business.model.Device;
import it.univaq.di.helpdesk.business.model.Faq;


public class IBATISDeviceService implements DeviceService {
	private SqlMapClient sqlMap;

	public IBATISDeviceService(SqlMapClient sqlMap) {
		super();
		this.sqlMap = sqlMap;
	}

	@Override
	public void addDevice(Device device) throws BusinessException {
		try {
			sqlMap.startTransaction();
			sqlMap.startBatch();
			
			sqlMap.insert("Device.addDevice", device);
			
			Device compositeDev = device.getComposite();
			//Il device che si sta aggiungendo è un composite (Computer)
			if (compositeDev != null) {
				Computer computer = (Computer)compositeDev;
				
				for(Device dev : computer.getDevices()) {
					dev.setParentDeviceID(device.getDeviceID());
					sqlMap.insert("Device.addDevice", dev);
				}
			}
			
			sqlMap.executeBatch();
			sqlMap.commitTransaction();
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		} finally {
			  try {
				sqlMap.endTransaction();
			} catch (SQLException e) {}
		}		
	}

	@Override
	public Device findDeviceById(int ID) throws BusinessException {
		Device device = null;
		
		try {
			device = (Device) sqlMap.queryForObject("Device.findDeviceById", ID);
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		}
		
		return device;
	}

	@Override
	public void deleteDevice(int ID) throws BusinessException {
		try {
			sqlMap.delete("deleteDevice", ID);
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		}
		
	}

	@Override
	public List<Device> findDeviceByUserId(int ID) throws BusinessException {
		List<Device> device = null;
		try {
			device = (List<Device>) sqlMap.queryForList("Device.findDeviceByUserId",ID);
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		}
		return device;
	}

	@Override
	public List<Device> searchForDevice(Map<String, String> queryParam)
			throws BusinessException {
		List<Device> devices = null;
		
		try {
			devices = (List<Device>) sqlMap.queryForList("Device.searchForDevice", queryParam);
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		}
		return devices;
	}

	@Override
	public void changeDeviceAssigned(Map<String, String> mapassigned) throws BusinessException {
		try {
			
			sqlMap.update("changeDeviceAssigned", mapassigned);
			
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		} 
		
	}

	@Override
	public Device getDeviceById(int ID) throws BusinessException {
		Device device = null;
		
		try {
			device = (Device) sqlMap.queryForObject("Device.getDevicesById", ID);
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		}
		
		return device;
	}

	@Override
	public void changeDeviceAssignedOffice(Map<String, String> mapassignedoffice) throws BusinessException {
		try {
			
			sqlMap.update("changeDeviceAssignedOffice", mapassignedoffice);
			
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		} 
		
	}

	@Override
	public boolean isDeviceAssigned(int deviceID) throws BusinessException {
		Integer result = new Integer(0);
		Integer ticketCount = new Integer(0);
		
		try {
			result = (Integer)sqlMap.queryForObject("isDeviceAssigned", deviceID);
			ticketCount = (Integer)sqlMap.queryForObject("countTicketByDeviceID", deviceID);
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		}
		
		return ((result > 0) || (ticketCount > 0));
	}

	@Override
	public void updateDevice(Device device) throws BusinessException {
		try {
			sqlMap.startTransaction();
			sqlMap.startBatch();

			Computer computer = (Computer) device.getComposite(); 
			if (computer != null) {
				sqlMap.delete("deleteChildDevice", device.getDeviceID());

				for (Device component: computer.getDevices()) {
					component.setParentDeviceID(device.getDeviceID());
					sqlMap.insert("Device.addDevice", component);
				}
				
			}
			
			sqlMap.update("updateDevice", device);
			
			sqlMap.executeBatch();
			sqlMap.commitTransaction();
		} catch (SQLException e) {
			throw new BusinessException(e.getMessage(),	e);
		} finally {
			try {
				sqlMap.endTransaction();
			} catch (SQLException e) {}
		}
	}
}
